#include <iostream>
#include <string>
#include <stdio.h>
#include "include/main.h"
#include "include/GlobalGameObj.h"
#include "include/Utils.h"
#include "include/EventParser.h"

// global game object list
map<int, GlobalGameObj *>gameObjectPool;

extern "C" int DllMain(int thread_id, char *buf, int *p_len)
{
#ifdef _DEBUG_LEVEL_1_
	cout << "in DllMain" << endl;
	char head_str[4096];
#endif

	GlobalGameObj *p_game_obj = gameObjectPool[thread_id];

	p_game_obj->p_package_head = PackageUtil::GetPackageHead(buf);

	// parse game head
	p_game_obj->p_data_head = PackageUtil::GetFirstDataHead(buf);

	p_game_obj->character_id = p_game_obj->p_data_head->character_id;
	p_game_obj->format = (Common::DataFormat)p_game_obj->p_data_head->format;
	p_game_obj->raw_data_len = p_game_obj->p_data_head->length * sizeof(int);
	p_game_obj->p_raw_data = (char *)p_game_obj->p_data_head + sizeof(struct Common::DataHead);

#ifdef _DEBUG_LEVEL_1_
	sprintf(head_str, "version:%d, protocol:%d, server:%d, server_type:%d,"
			"game:%d, length:%d, player_id:%d, character_id:%d, format:%d, len:%d",
			p_game_obj->p_package_head->version,
			p_game_obj->p_package_head->protocol,
			p_game_obj->p_package_head->server,
			p_game_obj->p_package_head->server_type,
			p_game_obj->p_package_head->game,
			p_game_obj->p_package_head->length,
			p_game_obj->p_package_head->player_id,
			p_game_obj->p_data_head->character_id,
			p_game_obj->p_data_head->format,
			p_game_obj->p_data_head->length);
	cout << head_str << endl;
#endif

	EventParser::ParseData(p_game_obj);
	if(Common::NoError != p_game_obj->error_code)
	{
		EventParser::ProcessSysError(p_game_obj);
	}

	*p_len = p_game_obj->package_len;

	return 0;
}

extern "C" int DllInit(char *p_config_file, int thread_id)
{
#ifdef _DEBUG_LEVEL_1_
	cout << "Enter Dll" << endl;
	cout << "config file: " << p_config_file << endl;
#endif

	GlobalGameObj *p_global_obj = new GlobalGameObj();
	p_global_obj->Init(p_config_file);
	gameObjectPool[thread_id] = p_global_obj;

	return 0;
}

extern "C" void DllExit(int thread_id)
{
#ifdef _DEBUG_LEVEL_1_
	cout << "Exit Dll" << endl;
#endif

	gameObjectPool[thread_id]->Exit();

	delete gameObjectPool[thread_id];
	gameObjectPool[thread_id] = NULL;
}
